<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <title>魔方</title>

    <!-- Babylon.js -->
    <script src="./js/pep.js"></script>
    <script src="./js/dat.gui.min.js"></script>
    <script src="./js/ammo.js"></script>
    <script src="./js/cannon.js"></script>
    <script src="./js/Oimo.js"></script>
    <script src="./js/libktx.js"></script>
    <script src="./js/earcut.min.js"></script>
    <script src="./js/babylon.js"></script>
    <script src="./js/babylon.inspector.bundle.js"></script>
    <script src="./js/babylonjs.materials.min.js"></script>
    <script src="./js/babylonjs.proceduralTextures.min.js"></script>
    <script src="./js/babylonjs.postProcess.min.js"></script>
    <script src="./js/babylonjs.loaders.js"></script>
    <script src="./js/babylonjs.serializers.min.js"></script>
    <script src="./js/babylon.gui.min.js"></script>

    <style>
        html, body {
            font-size: 14px;
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #renderCanvas {
            width: 100%;
            height: 100%;
            touch-action: none;
        }

        .floatingFrame {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            height: 0;
            z-index: 0;
        }

        .floatingFrame .main {
            color: #fff;
            width: 245px;
            float: right;
            margin-top: 15px;
            margin-right: 15px;
            overflow-y: visible;
            border-radius: 5px;
            border: 1px solid rgba(127, 255, 255, .75);
            box-shadow: 0 0 10px rgba(0, 255, 255, .95);
        }

        .floatingFrame .fileForm_label {
            display: inline-block;
            width: 60px;
        }

        .floatingFrame #keys {
            text-align: center;
            padding: 0px 10px 10px;
        }

        .floatingFrame .btn {
            text-align: center;
        }
    </style>
</head>
<body>
<canvas id="renderCanvas"></canvas>

<div class="floatingFrame">
    <div class="main">
        <h3 class="title">单元信息：</h3>
        <form action="##" id="keys">
            <label for="title" class="fileForm_label">序号</label>
            <input type="text" id="val" disabled>
            <br>
            <label for="title" class="fileForm_label">名称</label>
            <input type="text" id="title">
            <br>
            <label for="detail" class="fileForm_label">详细信息</label>
            <input type="text" id="detail">
            <br>
            <button class="btn">更新</button>
        </form>
    </div>
</div>
<script>
    var canvas = document.getElementById("renderCanvas");

    var engine = null;
    var scene = null;
    var sceneToRender = null;
    var createDefaultEngine = function () {
        /*
        * < BABYLON.Engine > 引擎
        * canvasOrContext: Nullable<HTMLCanvasElement | WebGLRenderingContext> 定义用于渲染的canvas或WebGL上下文。如果提供WebGL上下文，Babylon.js将不会在画布上挂接事件（如指针，键盘等），因此将没有事件可观察对象。当Babylon.js用作系统上使用WebGL上下文的插件时，通常使用此方法
        * antialias: boolean 定义启用平滑（默认值：false）
        * options: EngineOptions 定义要发送到getContext（）函数的更多选项 ==>详见《EngineOptions.md》
        * Returns Engine
        */
        return new BABYLON.Engine(canvas, true, {preserveDrawingBuffer: true, stencil: true});
    };
    var createScene = function () {

        // Create the scene space
        var scene = new BABYLON.Scene(engine);

        // Add a camera to the scene and attach it to the canvas
        /*
        * name: string 定义摄像机的名称
        * alpha: number 定义摄像机沿对数轴的旋转
        * beta: number 定义摄像机沿纬度轴的旋转
        * radius: number 定义相机到目标的距离
        * target: Vector3 定义相机目标
        * scene: Scene 定义相机所属的场景
        */
        // var camera = new BABYLON.ArcRotateCamera("Camera", 5 * Math.PI / 2.007, Math.PI / 2.07, 86, BABYLON.Vector3.Zero(), scene);
        var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 0, new BABYLON.Vector3(0, 0, -0), scene);
        camera.setPosition(new BABYLON.Vector3(0, 0, -20));
        camera.attachControl(canvas, true);
        // scene.useclonedmeshmap=true;
        // scene.useMaterialMeshMap=true;
        // scene.useGeometryIdsMap=true;
        // Add lights to the scene

        /*
        * < BABYLON.HemisphericLight > 半球光 Parameters
        * name: string
        * 友好的灯名称
        *
        * direction: Vector3
        * 光反射的方向
        *
        * scene: Scene
        * 灯光所属的场景
        */
        var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), scene);

        /*
        * < BABYLON.PointLight > 点光源 Parameters
        * name: string
        * 名称
        *
        * position: Vector3
        * The position of the point light in the scene
        * 灯光在场景中的位置
        * scene: Scene
        * 灯光所属的场景
        */
        var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), scene);

        var faceColors = [];
        faceColors[0] = BABYLON.Color3.Blue();
        faceColors[1] = BABYLON.Color3.Red();
        faceColors[2] = BABYLON.Color3.Green();
        faceColors[3] = BABYLON.Color3.White();
        faceColors[4] = BABYLON.Color3.Yellow();
        faceColors[5] = BABYLON.Color3.Black();

        // Add and manipulate meshes in the scene
        // 方的
        // height 高度	（数字）高度尺寸，覆盖尺寸属性	尺寸
        // width 宽度	（数字）宽度大小，覆盖大小属性	尺寸
        // depth 深度	（数字）深度大小，覆盖大小属性  尺寸

        // 模拟当前数据量
        for (let i = 0; i < 90; i++) {
            let box = BABYLON.MeshBuilder.CreateBox(i, {height: 1, width: 1, depth: 1}, scene);

            var materialBox = new BABYLON.StandardMaterial("boxMaterial", scene);
            // 给某个盒子设置颜色
            materialBox.diffuseColor = new BABYLON.Color3(0.89, 0.23, 0.61, 0.77);
            // 设置颜色
            box.material = materialBox;
            // 设置位置
            let margin = 1.4;  // 间距
            let column = 10;  // 列数
            let row = 3; // 行数
            let left = 5.5; // 与左侧的距离
            let top = 2; // 与顶部的距离
            let deepness = 3; // 深度
            let x = ((i % column) * margin) - left;
            let y = (-(Math.floor(i / column) % row) * margin) + top;
            let z = (Math.floor(i / (row * column))) * margin - deepness;
            box.position.x = x;
            box.position.y = y;
            box.position.z = z;

            //创建盒子文字
            var barLegend = BABYLON.Mesh.CreateGround("barLegend", scene);
            barLegend.position.x = box.position.x;
            barLegend.position.y = box.position.y;
            barLegend.position.z = box.position.z;
            // console.log(box.position.x,box.position.y+1, box.position.z)
            // box.material = new BABYLON.StandardMaterial("", scene);
            var barLegendTexture = new BABYLON.DynamicTexture("title texture", 140, scene, true);
            barLegendTexture.hasAlpha = true;
            box.material.diffuseTexture = barLegendTexture;
            box.material.emissiveColor = new BABYLON.Color3(0.4, 0.4, 0.4);
            barLegendTexture.drawText(box.name, 20, 20, "400 16px Segoe UI", "#ff4c1e", '#fff');
            barLegendTexture.drawText("Loading " + box.name, null, 70, "bold 16px Segoe UI", "blue", null);
            barLegendTexture.drawText("( statistics " + box.name + ")", null, 120, "20px Segoe UI", "blue", null);

            // 给盒子绑定点击事件
            box.actionManager = new BABYLON.ActionManager(scene);
            // new BABYLON.ExecuteCodeAction 创建一个执行代码
            box.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickUpTrigger, function (event) {
                // console.log(event.source.id)
                document.querySelector('#val').value = event.source.id;
                document.querySelector('#title').value = "Loading " + event.source.id;
                document.querySelector('#detail').value = "( statistics " + event.source.id + ")";
            }));
            // BABYLON.ActionManager.NothingTrigger：从不提出。用于具有action.then功能的子动作。
            // BABYLON.ActionManager.OnPickTrigger：当用户触摸/单击网格时引发。
            // BABYLON.ActionManager.OnDoublePickTrigger：在用户双击/单击网格时引发。
            // BABYLON.ActionManager.OnPickDownTrigger：当用户触摸/点击网格时引发
            // BABYLON.ActionManager.OnPickUpTrigger：当用户触摸/单击网格时引发。
            // BABYLON.ActionManager.OnPickOutTrigger：当用户触摸/向下单击网格然后移出网格时引发。
            // BABYLON.ActionManager.OnLeftPickTrigger：当用户使用左键触摸/单击网格时引发。
            // BABYLON.ActionManager.OnRightPickTrigger：当用户触摸/单击带有右键的网格时引发。
            // BABYLON.ActionManager.OnCenterPickTrigger：当用户触摸/单击带有中心按钮的网格时引发。
            // BABYLON.ActionManager.OnLongPressTrigger：当用户在毫秒内长时间触摸/单击网格时触发（由BABYLON.Scene.LongPressDelay定义）。
            // BABYLON.ActionManager.OnPointerOverTrigger：当指针在网格上方时引发。只举过一次。
            // BABYLON.ActionManager.OnPointerOutTrigger：当指针不再位于网格上方时引发。只举过一次。
            // BABYLON.ActionManager.OnIntersectionEnterTrigger：当网格与特定网格相交时引发。只举过一次。
            // BABYLON.ActionManager.OnIntersectionExitTrigger：当网格不再与特定网格相交时引发。只举过一次


            // 图例设置

            var blueMat = new BABYLON.StandardMaterial("blue", scene);
            blueMat.diffuseColor = new BABYLON.Color3(0, 0, 1, 0.77);

            var redMat = new BABYLON.StandardMaterial("red", scene);
            redMat.diffuseColor = new BABYLON.Color3(1, 0, 0, 0.77);

            var toSize = function (isChecked) {
                if (isChecked) {
                    box.scaling = new BABYLON.Vector3(0.5, 0.5, 0.5);
                } else {
                    box.scaling = new BABYLON.Vector3(1, 1, 1);
                }
            }

            var toPlace = function (isChecked) {
                if (isChecked) {
                    box.position.y += 1.5;
                } else {
                    box.position.y -= 1.5;
                }
            }

            // 设置立方体之间 间距
            var toMargin = function (but) {
                let margin,
                    column,
                    row,
                    left,
                    top,
                    deepness,
                    x,
                    y,
                    z;
                column = 10;  // 列数
                row = 3; // 行数
                left = .6; // 与左侧的距离 default 5.5
                top = .6; // 与顶部的距离 default 2
                deepness = .6; // 深度 default 3
                switch (but) {
                    case 0:
                        margin = 1.5;  // 间距
                        x = ((i % column) * margin) + left;
                        y = ((Math.floor(i / column) % row) * margin) + top;
                        z = (Math.floor(i / (row * column))) * margin + deepness;
                        box.position.x = x;
                        box.position.y = y;
                        box.position.z = z;
                        break;
                    case 1:
                        margin = 1.3;  // 间距
                        x = ((i % column) * margin) + left;
                        y = ((Math.floor(i / column) % row) * margin) + top;
                        z = (Math.floor(i / (row * column))) * margin + deepness;
                        box.position.x = x;
                        box.position.y = y;
                        box.position.z = z;
                        break;
                    case 2:
                        margin = 1.1;  // 间距
                        x = ((i % column) * margin) + left;
                        y = ((Math.floor(i / column) % row) * margin) + top;
                        z = (Math.floor(i / (row * column))) * margin + deepness;
                        box.position.x = x;
                        box.position.y = y;
                        box.position.z = z;
                        break;
                }
            };

            var setColor = function (but) {
                switch (but) {
                    case 0:
                        box.material = blueMat;
                        break;
                    case 1:
                        box.material = redMat;
                        break
                }
            };
            var orientateY = function (angle) {
                box.rotation.y = angle;
            };

            var displayValue = function (value) {
                return BABYLON.Tools.ToDegrees(value) | 0;
            };

            var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

            var selectBox = new BABYLON.GUI.SelectionPanel("sp");
            selectBox.width = 0.25;
            selectBox.height = 0.48;
            selectBox.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
            selectBox.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM;

            advancedTexture.addControl(selectBox);

            var transformGroup = new BABYLON.GUI.CheckboxGroup("变形");
            transformGroup.addCheckbox("缩小", toSize);
            transformGroup.addCheckbox("高", toPlace);

            // var colorGroup = new BABYLON.GUI.RadioGroup("Color");
            // colorGroup.addRadio("Blue", setColor, true);
            // colorGroup.addRadio("Red", setColor);

            var marginGroup = new BABYLON.GUI.RadioGroup("间距");
            marginGroup.addRadio('1.5', toMargin, true)
            marginGroup.addRadio('1.3', toMargin)
            marginGroup.addRadio('1.1', toMargin)

            // var rotateGroup = new BABYLON.GUI.SliderGroup("Rotation", "S");
            // rotateGroup.addSlider("Angle", orientateY, "degs", 0, 2 * Math.PI, 0, displayValue)

            selectBox.addGroup(transformGroup);
            // selectBox.addGroup(colorGroup);
            selectBox.addGroup(marginGroup);
            // selectBox.addGroup(rotateGroup);
        }
        // var box = BABYLON.MeshBuilder.CreateBox("box", { height: 1, width: 1, depth: 1}, scene);
        // var box2 = BABYLON.MeshBuilder.CreateBox("box2", {faceColors:faceColors,height: 1, width: 1, depth: 1}, scene);
        // var box3 = BABYLON.MeshBuilder.CreateBox("box2", {height: 1, width: 1, depth: 1}, scene);
        // var box1 = BABYLON.MeshBuilder.CreateBox("box1", {height: 1, width: 1, depth: 1}, scene);
        // var box5 = BABYLON.MeshBuilder.CreateBox("box2", {height: 1, width: 1, depth: 1}, scene);

        // box1.position.z = 1.5;
        // box2.position.z = 1.5;
        // box2.position.x = 1.5;
        // box3.position.z = 1.5;
        // box3.position.x = 3;
        // box5.position.z = 1.5;
        // box5.position.y = 1.5;

        // 圆的
        // diameterX 直径X	X轴上的（数字）直径，覆盖直径属性	直径
        // diameterY 直径Y	Y轴上的（数字）直径，覆盖直径属性	直径
        // diameterZ 直径Z	Z轴上的（数字）直径，覆盖直径属性
        // var mySphere = BABYLON.MeshBuilder.CreateSphere("mySphere", {diameter: 2, diameterX: 3,diameterZ: 1}, scene);

        // Add and manipulate meshes in the scene
        // 平面
        // height 高度	（数字）高度尺寸，覆盖尺寸属性	尺寸
        // width 宽度	（数字）宽度大小，覆盖大小属性	尺寸
        // var plane = BABYLON.MeshBuilder.CreatePlane("plane", {height:2, width: 1}, scene);


        // 添加背景
        var skybox = BABYLON.Mesh.CreateBox("BackgroundSkybox", 400, scene, undefined, BABYLON.Mesh.BACKSIDE);

        // Create and tweak the background material.
        var backgroundMaterial = new BABYLON.BackgroundMaterial("backgroundMaterial", scene);
        backgroundMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/TropicalSunnyDay", scene);
        backgroundMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
        skybox.material = backgroundMaterial;


        /*  轴线  */
        var showAxis = function (size) {
            var makeTextPlane = function (text, color, size) {
                var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true);
                dynamicTexture.hasAlpha = true;
                dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color, "transparent", true);
                var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true);
                plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);
                plane.material.backFaceCulling = false;
                plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
                plane.material.diffuseTexture = dynamicTexture;
                return plane;
            };

            //Vector3(size, 0, 0)  x,y,z
            var axisX = BABYLON.Mesh.CreateLines("axisX", [
                new BABYLON.Vector3.Zero(), new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, 0.05 * size, 0),
                new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)
            ], scene);
            axisX.color = new BABYLON.Color3(1, 0, 0);
            var xChar = makeTextPlane("X", "red", size / 10);
            xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);
            var axisY = BABYLON.Mesh.CreateLines("axisY", [
                new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3(-0.05 * size, size * 0.95, 0),
                new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3(0.05 * size, size * 0.95, 0)
            ], scene);
            axisY.color = new BABYLON.Color3(0, 1, 0);
            var yChar = makeTextPlane("Y", "green", size / 10);
            yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
            var axisZ = BABYLON.Mesh.CreateLines("axisZ", [
                new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3(0, -0.05 * size, size * 0.95),
                new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3(0, 0.05 * size, size * 0.95)
            ], scene);
            axisZ.color = new BABYLON.Color3(0, 0, 1);
            var zChar = makeTextPlane("Z", "blue", size / 10);
            zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
        };


        showAxis(10);


        return scene;

    };
    var engine;
    try {
        engine = createDefaultEngine();
    } catch (e) {
        console.log("the available createEngine function failed. Creating the default engine instead");
        engine = createDefaultEngine();
    }
    if (!engine) throw 'engine should not be null.';
    scene = createScene();
    sceneToRender = scene;

    engine.runRenderLoop(function () {
        if (sceneToRender) {
            sceneToRender.render();
        }
    });

    // Resize
    window.addEventListener("resize", function () {
        engine.resize();
    });
</script>
</body>
</html>
